package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.common.exceptions.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.model.enums.ItemType;
import com.atguigu.lease.model.enums.ReleaseStatus;
import com.atguigu.lease.web.admin.mapper.*;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentDetailVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentItemVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentQueryVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentSubmitVo;
import com.atguigu.lease.web.admin.vo.fee.FeeValueVo;
import com.atguigu.lease.web.admin.vo.graph.GraphVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author liubo
 * @description 针对表【apartment_info(公寓信息表)】的数据库操作Service实现
 * @createDate 2023-07-24 15:48:00
 */
@Service
public class ApartmentInfoServiceImpl extends ServiceImpl<ApartmentInfoMapper, ApartmentInfo>
        implements ApartmentInfoService {

    @Autowired
    private ApartmentInfoMapper apartmentInfoMapper;

    @Autowired
    private ApartmentFacilityService apartmentFacilityService;
    @Autowired
    private ApartmentFeeValueService apartmentFeeValueService;
    @Autowired
    private GraphInfoService graphInfoService;
    @Autowired
    private ApartmentLabelService apartmentLabelService;

    @Autowired
    private GraphInfoMapper graphInfoMapper;
    @Autowired
    private LabelInfoMapper labelInfoMapper;
    @Autowired
    private FacilityInfoMapper facilityInfoMapper;
    @Autowired
    private FeeValueMapper feeValueMapper;

    @Autowired
    private RoomInfoService roomInfoService;

    @Override
    public void customSaveOrUpdate(ApartmentSubmitVo apartmentSubmitVo) {
        //1.检查本次是保存还是更新
        boolean isUpdate = apartmentSubmitVo.getId()!=null;
        //2.调用mybatis-plus提供的saveOrUpdate方法完成vo的操作
        saveOrUpdate(apartmentSubmitVo); //保存或者更新到公寓表

        Long apartmentId = apartmentSubmitVo.getId();
        //3.如果是更新,先删除中间表的数据
        if (isUpdate){
            //删除配套和公寓的中间表
            LambdaQueryWrapper<ApartmentFacility> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(ApartmentFacility::getApartmentId,apartmentId);
            apartmentFacilityService.remove(lambdaQueryWrapper);
            //删除杂费和公寓中间表
            LambdaQueryWrapper<ApartmentFeeValue> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper1.eq(ApartmentFeeValue::getApartmentId,apartmentId);
            apartmentFeeValueService.remove(lambdaQueryWrapper1);
            //删除标签和公寓中间表
            LambdaQueryWrapper<ApartmentLabel> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper2.eq(ApartmentLabel::getApartmentId,apartmentId);
            apartmentLabelService.remove(lambdaQueryWrapper2);
            //删除图片和公寓中间表
            LambdaQueryWrapper<GraphInfo> lambdaQueryWrapper3 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper3.eq(GraphInfo::getItemType, ItemType.APARTMENT);
            lambdaQueryWrapper3.eq(GraphInfo::getItemId,apartmentId);
            graphInfoService.remove(lambdaQueryWrapper3);
        }
        //4.插入中间表相关的数据
        if (!CollectionUtils.isEmpty(apartmentSubmitVo.getFacilityInfoIds())){
            List<ApartmentFacility> apartmentFacilityList = new ArrayList<>();
            for (Long facilityInfoId : apartmentSubmitVo.getFacilityInfoIds()) {
                ApartmentFacility apartmentFacility = ApartmentFacility.builder().apartmentId(apartmentId).facilityId(facilityInfoId).build();
                apartmentFacilityList.add(apartmentFacility);
            }
            apartmentFacilityService.saveBatch(apartmentFacilityList); //1.对应实体类的集合 2.批量保存
        }

        if (!CollectionUtils.isEmpty(apartmentSubmitVo.getFeeValueIds())){
            List<ApartmentFeeValue> apartmentFeeValueList = new ArrayList<>();
            for (Long feeValueId : apartmentSubmitVo.getFeeValueIds()) {
                ApartmentFeeValue apartmentFeeValue = ApartmentFeeValue.builder().apartmentId(apartmentId).feeValueId(feeValueId).build();
                apartmentFeeValueList.add(apartmentFeeValue);
            }
            apartmentFeeValueService.saveBatch(apartmentFeeValueList);
        }

        if (!CollectionUtils.isEmpty(apartmentSubmitVo.getLabelIds())){
            List<ApartmentLabel> apartmentLabelList = new ArrayList<>();
            for (Long labelId : apartmentSubmitVo.getLabelIds()) {
                ApartmentLabel apartmentLabel = ApartmentLabel.builder().apartmentId(apartmentId).labelId(labelId).build();
                apartmentLabelList.add(apartmentLabel);
            }
            apartmentLabelService.saveBatch(apartmentLabelList);
        }

        //图片
        if (!CollectionUtils.isEmpty(apartmentSubmitVo.getGraphVoList())){
            List<GraphInfo> graphInfoList = new ArrayList<>();
            for (GraphVo graphVo : apartmentSubmitVo.getGraphVoList()) {
                GraphInfo graphInfo = new GraphInfo();
                graphInfo.setName(graphVo.getName());
                graphInfo.setUrl(graphVo.getUrl());
                graphInfo.setItemId(apartmentId);
                graphInfo.setItemType(ItemType.APARTMENT);
                graphInfoList.add(graphInfo);
            }
            graphInfoService.saveBatch(graphInfoList);
        }
    }

    @Override
    public Page<ApartmentItemVo> customPage(Page<ApartmentItemVo> page, ApartmentQueryVo queryVo) {
        return apartmentInfoMapper.queryPage(page,queryVo);
    }


    /**
     * 根据id查询公寓详情
     * 原本可以利用多表查询 9张表联查，但是我们拆成多个单表操作
     *  1.根据公寓id查询公寓的详情
     *  2.根据公寓id查询公寓的图片vo集合
     *  3.根据公寓id查询公寓的配套集合
     *  4.根据公寓id查询公寓的标签集合
     *  5.根据公寓id查询公寓的杂费集合
     *  6.组合数据到ApartmentDetailVo返回即可
     * @param id
     * @return
     */
    @Override
    public ApartmentDetailVo customDetail(Long id) {
        // 1.根据公寓id查询公寓的详情
        ApartmentInfo apartmentInfo = getById(id);
        // 2.根据公寓id查询公寓的图片vo集合
        List<GraphVo> graphVoList =  graphInfoMapper.queryVoList(ItemType.APARTMENT,id);
        // 3.根据公寓id查询公寓的配套集合
        List<FacilityInfo> facilityInfoList = facilityInfoMapper.queryList(id);
        // 4.根据公寓id查询公寓的标签集合
        List<LabelInfo> labelInfoList = labelInfoMapper.queryList(id);
        // 5.根据公寓id查询公寓的杂费集合
        List<FeeValueVo> feeValueVoList = feeValueMapper.queryVoList(id);
        // 6.组合数据到ApartmentDetailVo返回即可
        ApartmentDetailVo apartmentItemVo = new ApartmentDetailVo();
        //对象之间的属性复制
        BeanUtils.copyProperties(apartmentInfo,apartmentItemVo);
        apartmentItemVo.setGraphVoList(graphVoList);
        apartmentItemVo.setFacilityInfoList(facilityInfoList);
        apartmentItemVo.setLabelInfoList(labelInfoList);
        apartmentItemVo.setFeeValueVoList(feeValueVoList);
        return apartmentItemVo;
    }


    /**
     * 考虑到公寓关联到多个表结构！其中房间的数据较为重要！
     *   1.删除公寓之前，先考虑是否由房间，有不允许删除
     *   2.没有，删除公寓，以及公寓关联的四个中间表
     * @param id
     */
    @Override
    public void customRemove(Long id) {
        //公寓id , 发布状态的房间
        LambdaQueryWrapper<RoomInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(RoomInfo::getApartmentId,id);
        lambdaQueryWrapper.eq(RoomInfo::getIsRelease, ReleaseStatus.RELEASED);
        long count = roomInfoService.count(lambdaQueryWrapper);
        if (count >0){
            //有房间，不能删除
            //1. 终止删除动作 2.且给前端对应的提示 [方法修改返回值(不用)|异常流(抛异常，全局异常处理器)]
            throw new LeaseException(ResultCodeEnum.DELETE_ERROR);
        }

        //删除配套中间表
        LambdaQueryWrapper<ApartmentFacility> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper1.eq(ApartmentFacility::getApartmentId,id);
        apartmentFacilityService.remove(lambdaQueryWrapper1);

        //删除标签中间表
        LambdaQueryWrapper<ApartmentLabel> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper2.eq(ApartmentLabel::getApartmentId,id);
        apartmentLabelService.remove(lambdaQueryWrapper2);

        //删除杂费中间表
        LambdaQueryWrapper<ApartmentFeeValue> lambdaQueryWrapper3 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper3.eq(ApartmentFeeValue::getApartmentId,id);
        apartmentFeeValueService.remove(lambdaQueryWrapper3);

        LambdaQueryWrapper<GraphInfo> lambdaQueryWrapper4 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper4.eq(GraphInfo::getItemId,id);
        lambdaQueryWrapper4.eq(GraphInfo::getItemType,ItemType.APARTMENT);
        graphInfoService.remove(lambdaQueryWrapper4);

        removeById(id);
    }
}




